<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width,initial-scale=1">
	<link rel="shortcut icon" href="/favicon.ico">
	<title>J-IM:支持百万在线用户</title>
	<style type="text/css" media="screen">
		*{margin:0;padding:0;}
		#wrap{margin:10px auto; width:80%; height:99%;}
		.unit{margin-bottom:5px; padding:5px; border:solid 1px #000; height:auto;  clear:both;box-sizing:border-box;}
		.unit label{text-align:right;width:100px;line-height: 30px; display:inline-block;}
		.unit input{line-height: 30px; width:100px; height:30px;}
		.log {font-size:11px; font-family:Courier; overflow: auto; height:100%; background:black;width:85%;float:left}
		.log p{padding:2px;margin:0;}
		.content{width:100%;overflow:hidden;height:80%;margin:0 0 5px 0;}
		.online{width: 15%;height: 100%;float:right;background: #FCFCFC;border:solid 1px #000;box-sizing:border-box;}
	</style>
	<script type="text/javascript" src="./static/js/date.js"></script>
</head>
<script type="text/javascript">
	var socket ;
	var logDiv;
	var username;
	var onSelected;
	var curUser;
	var friends = [];
	var groups = [];


	function init() {
		var ip = document.getElementById("serverIp").value;
		var port = document.getElementById("port").value;
		console.log("init");
		socket = new WebSocket("ws://"+ip+":"+port);
		socket.onopen = function(e){
			console.log(e);
		};

		socket.onerror = function(e){
			logDiv.innerHTML+="<font color='red' size='1'>异常:"+e+"</font><br>";
			scrollToBottom();
		};
		socket.onclose = function(e){
			curUser = null;
			logDiv.innerHTML+="<font color='green' size='1'>关闭连接...</font><br>";
			document.getElementById("onlinePanel").innerHTML="&nbsp;在线成员(0/0)";
			scrollToBottom();
		};
		socket.onmessage = function(e){
			var data = e.data;
			var dataObj = eval("("+data+")");//转换为json对象
			if(dataObj.command == 11){//接收到聊天响应处理;
				COMMAND_CHAT_RESP(dataObj);
			}else if(dataObj.command == 18){//获取用户信息响应处理;
				COMMAND_GET_USER_RESP(dataObj);
			}else if(10000 == dataObj.code && dataObj.command == 12){//聊天发送状态;
				COMMAND_CHAT_RESP_SEND_STATUS(data);
			}else if(dataObj.command == 9){//加入群组的消息通知处理;
				COMMAND_JOIN_GROUP_NOTIFY_RESP(dataObj);
			}else if(dataObj.command == 10){
				COMMAND_EXIT_GROUP_NOTIFY_RESP(dataObj);
			}else if(dataObj.command == 20 && dataObj.code == 10015){
				//获取消息失败，未开启持久化处理
				//...
			}else if(dataObj.command == 20 && dataObj.code == 10016){//处理离线消息;
				var msgFlag = "离线消息";
				COMMAND_GET_MESSAGE_RESP(dataObj,msgFlag);
			}else if(dataObj.command == 20 && dataObj.code == 10018){//处理历史消息;
				var msgFlag = "历史消息";
				var msgObj = dataObj.data;
				if(msgObj){
					COMMAND_GET_MESSAGE_RESP(dataObj,msgFlag);
				}else{//没有历史消息;
					OTHER(data);
				}
			}else if(dataObj.command == 6){//登陆命令返回状态处理
				COMMAND_LOGIN_RESP(dataObj,data);
			}else{
				OTHER(data);
			}
			scrollToBottom();
		};

	}


	function connect(){
		// if(curUser){
		// 	alert("当前已登录,请先退出登录!");
		// 	return;
		// }
		username = document.getElementById("username").value;
		var password = document.getElementById("password").value;
		logDiv = document.getElementById('logs');

		var login = {
			cmd:5,
			userid:username,
			password:password
		};
		socket.send(JSON.stringify(login));//获取登录用户信息;
	}
	//登陆通知处理
	function COMMAND_LOGIN_RESP(dataObj,data){
		if(10007 == dataObj.code){//登陆成功;
			logDiv.innerHTML+="<font color='green' size='1'>连接成功...</font><br>";
			var userCmd = "{\"cmd\":17,\"type\":\"0\",\"userId\":\""+username+"\"}";
			var msgCmd = "{\"cmd\":19,\"type\":\"0\",\"userId\":\""+username+"\"}";
			socket.send(userCmd);//获取登录用户信息;
			// socket.send(msgCmd);//获取用户离线消息(好友+群组);
			scrollToBottom();
		}else if(10008 == dataObj.code){//登录失败;
			OTHER(data);
		}
	}
	function COMMAND_EXIT_GROUP_NOTIFY_RESP(data){
		var exitGroupNotify = data.data;
		var onlineUserCmd = "{\"cmd\":17,\"type\":\"0\",\"userId\":\""+curUser.userId+"\"}";
		logDiv.innerHTML+="<font color='#A3A3A3' size='1'>"+exitGroupNotify.user.nick+"("+exitGroupNotify.user.userId+")退出群聊...</font><br>";
		socket.send(onlineUserCmd);//获取在线用户列表;
	}
	//加入群组的消息通知处理;
	function COMMAND_JOIN_GROUP_NOTIFY_RESP(data){
		var user = data.user;
		logDiv.innerHTML+="<font color='#A3A3A3' size='1'>"+user.nick+"("+user.userId+")加入群聊...</font><br>";
		var onlineUserCmd = "{\"cmd\":17,\"type\":\"0\",\"userId\":\""+curUser.userId+"\"}";
		socket.send(onlineUserCmd);//获取在线用户列表;
	}
	//加入群组响应状态处理;
	function COMMAND_JOIN_GROUP_RESP(data){
		//成功加入群组响应信息;
	}
	//发送聊天请求发送状态处理;
	function COMMAND_CHAT_RESP_SEND_STATUS(data){
		//发送成功后的状态处理...
	}
	//获取用户信息响应处理;
	function COMMAND_GET_USER_RESP(data){
		console.log(data);
		var user =  data.data;
		curUser = user;
		initOnlineUsers();
	}
	//接收到聊天响应处理;
	function COMMAND_CHAT_RESP(data){
		var chatObj = data.data;
		var createTime = new Date(chatObj.createTime).Format("yyyy/MM/dd HH:mm:ss");
		var from = chatObj.from;
		if(from == username)
			return;
		var content = chatObj.content;
		var user = getOnlineUserById(from);
		if(user){
			logDiv.innerHTML+="<font color='#009ACD' size='1' style='font-weight: bold'>"+user.nick+"("+user.id+")"+" "+createTime+"</font><br>";
		}else{
			logDiv.innerHTML+="<font color='#009ACD' size='1' style='font-weight: bold'>"+from+" "+createTime+"</font><br>";
		}
		//处理数据
		logDiv.innerHTML+="<font color='#FFFFFF' size='1'>&nbsp;"+content+"</font><br>";
	}
	//处理用户同步+持久化消息
	function COMMAND_GET_MESSAGE_RESP(data,msgFlag){
		var msgObj = data.data;
		friendOfflineMessage(msgObj,msgFlag);
		groupOfflineMessage(msgObj,msgFlag);
	}
	//好友消息
	function friendOfflineMessage(msgObj,msgFlag){
		var friends = msgObj.friends;
		for (var key in friends) {
			var chatDatas = friends[key];
			for(var index in chatDatas){
				var user_id = chatDatas[index].from;
				var createTime = new Date(chatDatas[index].createTime).Format("yyyy/MM/dd HH:mm:ss");
				logDiv.innerHTML+="<font color='	#009ACD' size='1' style='font-weight: bold'>"+user_id+"</font><font color='#DC143C' size='1' style='font-weight: bold'>(好友"+msgFlag+")</font>"+"<font color='#009ACD' size='1' style='font-weight: bold'>"+createTime+"</font><br>";
				logDiv.innerHTML+="<font color='#FFFFFF' size='1'>&nbsp;"+chatDatas[index].content+"</font><br>";
			}
		}
	}
	//群组消息
	function groupOfflineMessage(msgObj,msgFlag){
		var groups = msgObj.groups;
		for (var key in groups) {
			var chatDatas = groups[key];
			for(var index in chatDatas){
				var user_id = chatDatas[index].from;
				var createTime = new Date(chatDatas[index].createTime).Format("yyyy/MM/dd HH:mm:ss");
				logDiv.innerHTML+="<font color='	#009ACD' size='1' style='font-weight: bold'>"+user_id+"</font><font color='#DC143C' size='1' style='font-weight: bold'>(群聊["+chatDatas[index].groupId+"]"+msgFlag+")</font>"+"<font color='#009ACD' size='1' style='font-weight: bold'>"+createTime+"</font><br>";
				logDiv.innerHTML+="<font color='#FFFFFF' size='1'>&nbsp;"+chatDatas[index].content+"</font><br>";
			}
		}
	}
	//其它信息处理;
	function OTHER(data){
		//处理数据
		logDiv.innerHTML+="<font color='green' size='1'>"+data+"</font><br>";
	}
	function getOnlineUserById(id){
		var groups = curUser.groups;
		var onlineUserStr = "";
		for(var g = 0 ; g < groups.length ; g++){
			var group = groups[g];
			var users = group.users;
			for(var u = 0 ; u < users.length ; u++){
				var user = users[u];
				if(user.id == id){
					return user;
				}
			}
		}
	}
	function initOnlineUsers(){
		var groups = curUser.groups;
		var onlineUserStr = "";
		for(var g = 0 ; g < groups.length ; g++){
			var group = groups[g];
			var users = group.users;
			onlineUserStr += "&nbsp;"+group.name+"在线成员("+users.length+"/"+users.length+")";
			for(var u = 0 ; u < users.length ; u++){
				var user = users[u];
				onlineUserStr +="<div id=\""+user.userId+"\" nick=\""+user.nick+"\" style=\"line-height: 25px;margin: 5px 5px 0 5px;padding-left:15px;cursor:pointer;\" onclick=\"onlineDb(this);\" onmouseover=\"onlineMove(this);\"  onmouseleave=\"onlineLeave(this);\"><img alt=\""+user.userId+"\" src=\""+user.avatar+"\" height=\"25px\" width=\"25px;\" style=\"float:left\">&nbsp;<font size='2'>"+user.nick+"("+user.userId+")</font></div>";
			}
		}
		if(!onlineUserStr){
			onlineUserStr = "&nbsp;在线成员(0/0)";
		}
		document.getElementById("onlinePanel").innerHTML = onlineUserStr;
	}
	function disConnect(){
		socket.close();
	}

	function send(){
		var toId = "";
		if(onSelected){
			toId = onSelected.getElementsByTagName("img")[0].alt;
		}
		var createTime = new Date().getTime();
		var content = document.getElementById('content').value;
		if(content == "")
			return ;
		var msg = "{\"from\": \""+username+"\",\"to\": \""+toId+"\",\"cmd\":11,\"createTime\":"+createTime+",\"chatType\":\"2\",\"msgType\": \"0\",\"content\": \""+content+"\"}";
		if(!toId){
			alert("请选择要私聊的人!");
			return;
		}
		if(toId == username){
			alert("无法给自己发送消息!");
			return ;
		}
		socket.send(msg);
		var chatObj = eval("("+msg+")");
		var createTime = new Date(chatObj.createTime).Format("yyyy/MM/dd HH:mm:ss");
		//处理数据
		logDiv.innerHTML+="<font color='#228B22' size='1' style='font-weight: bold'>"+chatObj.from+" "+createTime+"</font><br>";
		//处理数据
		logDiv.innerHTML+="<font color='#FFFFFF' size='1'>&nbsp;"+chatObj.content+"</font><br>";
		document.getElementById('content').value = "";
	}
	function sendGroup(){
		var createTime = new Date().getTime();
		var content = document.getElementById('content').value;
		if(content == "")
			return ;
		var msg = "{\"from\": \""+username+"\",\"createTime\":"+createTime+",\"cmd\":11,\"groupId\":\"100\",\"chatType\":\"1\",\"msgType\":\"0\",\"content\": \""+content+"\"}";
		socket.send(msg);
		var chatObj = eval("("+msg+")");
		var createTime = new Date(chatObj.createTime).Format("yyyy/MM/dd HH:mm:ss");
		//处理数据
		logDiv.innerHTML+="<font color='#228B22' size='1' style='font-weight: bold'>"+curUser.nick+"("+curUser.userId+")"+" "+createTime+"</font><br>";
		//处理数据
		logDiv.innerHTML+="<font color='#FFFFFF' size='1'>&nbsp;"+chatObj.content+"</font><br>";
		document.getElementById('content').value = "";
	}
	function scrollToBottom(){
		var logDiv = document.getElementById('logs');
		logDiv.scrollTop = logDiv.scrollHeight;
	}
	function clearLogs(){
		var logDiv = document.getElementById('logs');
		logDiv.innerHTML="";
	}
	function showServerConfig(obj){
		var target = document.getElementById("serverConfigId");
		if (target.style.display=="block"){
			target.style.display="none";
			obj.value="服务器配置";
		} else {
			target.style.display="block";
			obj.value='关闭配置';
		}
	}
	function onlineDb(obj){
		if(onSelected){
			if(onSelected.id != obj.id){
				onSelected.style.background = "";
			}
		}
		obj.style.background = "#D4D4D4";
		onSelected = obj;
		var sendBtn = document.getElementById("sendBtn");
		sendBtn.style="width: 150px;"
		sendBtn.value="发送给:"+onSelected.id;
	}
	function onlineMove(obj){
		if("undefined" == typeof(onSelected) || onSelected.id != obj.id){
			obj.style.background = "#F0F0F0";
		}
	}
	function onlineLeave(obj){
		var onlineDiv = document.getElementById("onlinePanel").getElementsByTagName("div");
		for(var i =0 ; i < onlineDiv.length ; i++){
			if("undefined" == typeof(onSelected) || onSelected.id != onlineDiv[i].id){
				onlineDiv[i].style.background = "";
			}
		}
	}
	function setUserName(){
		document.getElementById("username").value = new Date().getTime();
	}
	function keyDown(e) {
		var ev= window.event||e;
		//13是键盘上面固定的回车键
		if (ev.keyCode == 13) {
			sendGroup();
		}
	}
	function authCmd(){
		if(!curUser){
			alert("demo中模拟命令需要先登录，请先登录!");
		}
		var authCmd = "{\"cmd\":3,\"token\":\"校验码\"}";
		socket.send(authCmd);
	}
	function heartbeatCmd(){
		if(!curUser){
			alert("demo中模拟命令需要先登录，请先登录!");
		}
		var heartbeatCmd = "{\"cmd\":13,\"hbbyte\":\"-127\"}";
		socket.send(heartbeatCmd);
	}

	function friendHistoryCmd(){
		if(!curUser){
			alert("请先登录!");
			return;
		}
		var friend_id = document.getElementById("history_friend_id").value;;
		if(friend_id == ""){
			alert("请输入要获取的好友ID!");
			return;
		}
		var msgHistoryCmd = "{\"cmd\":19,\"type\":\"1\",\"fromUserId\":\""+friend_id+"\",\"userId\":\""+username+"\"}";
		socket.send(msgHistoryCmd);//获取用户历史消息;
	}

	function groupHistoryCmd(){
		if(!curUser){
			alert("请先登录!");
			return;
		}
		var group_id = document.getElementById("history_group_id").value;;
		if(group_id == ""){
			alert("请输入要获取的群组ID!");
			return;
		}
		var msgHistoryCmd = "{\"cmd\":19,\"type\":\"1\",\"groupId\":\""+group_id+"\",\"userId\":\""+username+"\"}";
		socket.send(msgHistoryCmd);//获取群组历史消息;
	}
</script>
<body onload="setUserName();">
<div id="wrap" style="height:600px;">
	<div class="unit">
		<label >用户名:</label>
		<input  id="username" value=""/>
		<label style="width: 60px;">密码:</label>
		<input  id="password" value ="123"/>
		<input onclick="connect();"  type="button" value="登录1" />
		<input onclick="javascript:disConnect();" type="button" value="退出" />
		<input onclick="javascript:init();" type="button" value="连接服务器" />
		<input onclick="javascript:showServerConfig(this);" type="button" value="服务器配置" />
	</div>
	<div class="unit" id="serverConfigId" style="display: none;">
		<label >服务器IP:</label>
		<input  id="serverIp" value="localhost"/>
		<label>端口号:</label>
		<input  id="port" value ="8888"/>
	</div>
	<div class="unit">
		<label>聊天记录:</label>
		<input type="button" value="清空记录" onclick="clearLogs();"/>
		<input type="button" value="鉴权命令" onclick="authCmd();"/>
		<input type="button" value="心跳命令" onclick="heartbeatCmd();"/>
		<input type="button" value="获取指定好友历史消息" onclick="friendHistoryCmd();" style="width: 150px;"/>
		<input id="history_friend_id" style="width:100px;" placeholder="输入好友ID"/>
		<input type="button" value="获取指定群组历史消息" onclick="groupHistoryCmd();" style="width: 150px;"/>
		<input id="history_group_id" style="width:100px;" placeholder="输入群组ID"/>
	</div>
	<div class="content">
		<div id="logs" class="unit log">
		</div>
		<div id="onlinePanel" class="online">
			&nbsp;在线成员(0/0)
		</div>
	</div>
	<div class="unit">
		<label >输入内容:</label>
		<input id="content" style="width:500px;" onkeydown="keyDown(event)"/>
		<input onclick="javascript:sendGroup()" id="sendGroupBtn"  type="button"  value="群聊" />&nbsp;<input onclick="javascript:send()" id="sendBtn"  type="button"  value="私聊" />
	</div>
</div>
</body>
</html>
